/**
 * Created with JavaScript.
 * User: rgxmg
 * Email: rgxmg@foxmail.com
 * Date: 2021/1/19
 * Time: 9:37
 *
 */
import TProps from "./TProps";
export default {
  props: {
    ...TProps,
    // 选项配置，用于生成table的el-table-column子元素
    // 每一个item配置如下：
    // {
    //   title {String} 名称
    //   dataIndex {String} 字段名称
    //   width {Number} 宽度
    //   render {Function(row: Object, index: Number): VNode} 用于自定义渲染
    //   props {Object} column的props参数
    // }
    options: {
      required: true,
      type: Array
    },

    // 加载数据的Function
    // 该函数必须返回promise
    // 且返回值中必须为两种类型：
    //  1. Object: { total {Number|String}, list {Array} }
    //  2. Array: 同Object的list，直接返回Array, 必须手动关闭pagination，即设置pagination=false
    data: [Function, Array],

    // 分页器配置
    // 1. 为false，则表示不显示分页
    // 2. 为object,则传入分页器的props配置，同el-pagination的props，默认的props为{ pageSize: 10, total: 0, layout: "prev, next, total, pager" }
    pagination: {
      type: [Boolean, Object],
      default: () => ({})
    },

    // total的文字描述
    // 传入pagination的当前值
    // 【警告】必须在pagination中开启layout中的total选项
    totalText: {
      type: Function,
      default: (...args) => {
        console.log(args);
      }
    },

    // 自动加载数据
    auto: {
      type: Boolean,
      default: true
    }
  },
  created() {
    this.handleMergePagination();
  },
  mounted() {
    this.auto && this.loadData();
  },
  data() {
    return {
      dataSource: [],

      // 是否显示分页器
      showPagination: true,

      paginationProps: {},
      localPagination: {
        currentPage: 1,
        pageSize: 10,
        total: 0,
        layout: "total, prev, pager, next, sizes"
      }
    };
  },
  methods: {
    resetRefresh(toTop = true) {
      this.paginationProps.currentPage = 1;
      this.refresh(toTop);
    },
    refresh(toTop = true) {
      if (toTop) {
        window.scroll({ behavior: "smooth", top: toTop - 0 });
      }
      this.loadData();
    },
    loadData() {
      if (Array.isArray(this.data)) {
        this.dataSource = this.data;
        this.paginationProps.total = this.data.length;
        return;
      }
      const { currentPage, pageSize } = this.paginationProps;
      this.data({ pageNum: currentPage, pageSize }).then(res => {
        if (this.pagination === false) {
          if (Array.isArray(res)) {
            this.dataSource = res;
          } else {
            throw new Error("when Pagination is closed, the data return value must be type Array");
          }
        } else {
          // 验证res的数值
          const { total, list } = res || { total: 0, list: [] };
          this.dataSource = list;
          this.paginationProps.total = total;
        }
      });
    },

    getTable() {
      const props = {
        props: {
          ...this.$props,
          data: this.dataSource
        },
        on: this.$listeners,
        directives: [{ name: "ref", value: r => this.$emit("ref", r) }]
      };
      return (
        <el-table {...props}>
          {this.options.map(i => {
            let props = {
              props: {
                label: i.title,
                prop: i.dataIndex,
                width: i.width,
                ...(i.props || {})
              }
            };
            if (i.render) {
              props.scopedSlots = {
                default: i.render
              };
            }
            return <el-table-column {...props} />;
          })}
        </el-table>
      );
    },

    /**
     * 处理合并新的pagination参数
     */
    handleMergePagination() {
      this.showPagination = this.pagination !== false;
      if (typeof this.pagination !== "boolean") {
        this.paginationProps = {
          ...this.localPagination,
          ...this.pagination
        };
      }
    },

    getPagination() {
      let props = {
        props: {
          ...this.paginationProps
        },
        on: {
          "current-change": c => {
            this.$emit("pageChange", c);
            this.paginationProps.currentPage = c;
            this.loadData();
          },
          "size-change": s => {
            this.$emit("sizeChange", s);
            this.paginationProps.pageSize = s;
            this.loadData();
          }
        }
      };
      if (this.totalText) {
        props.scopedSlots = {
          total: this.totalText
        };
      }
      return <el-pagination {...props} />;
    }
  },
  watch: {
    data(v) {
      if (v) {
        this.auto && this.loadData();
      }
    }
  },
  render() {
    return (
      <div>
        {this.getTable()}
        {this.showPagination ? <div style="text-align: right; margin-top: 20px">{this.getPagination()}</div> : null}
      </div>
    );
  }
};
